﻿using System;
using MugenInjection.Delegates;
using MugenInjection.Interface;

namespace MugenInjection.Syntax.Type
{
    /// <summary>
    /// Specific fluent syntax for type binding.
    /// </summary>
    public interface ITypeUseSyntax : IBindingBuilder
    {
        /// <summary>
        /// Indicates that the service should be use reflection activator for create new instance of object.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax UseReflectionActivator();

#if !NETFX_CORE
        /// <summary>
        /// Indicates that the service should be use emit activator for create new instance of object.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax UseEmitActivator();
#endif
#if !NOEXPRESSION

        /// <summary>
        /// Indicates that the service should be use expression activator for create new instance of object.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax UseExpressionActivator();
#endif

        /// <summary>
        /// Indicates that the service should be use custom activator for create new instance of object.
        /// </summary>
        /// <param name="activator">The specified <see cref="IActivator"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax UseCustomActivator(IActivator activator);

        /// <summary>
        /// Indicates that the service should be use custom activator for create new instance of object.
        /// </summary>
        /// <param name="methodActivator">The specified <see cref="Func{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax UseCustomActivator(Func<IActivator> methodActivator);

        /// <summary>
        /// Indicates that the service should be use custom constructor resolver for select constructor for specified service.
        /// </summary>
        /// <param name="constructorResolver">The specified <see cref="IConstructorResolver"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax UseCustomConstructorResolver(IConstructorResolver constructorResolver);

        /// <summary>
        /// Indicates that the service should be use custom constructor resolver for select constructor for specified service.
        /// </summary>
        /// <param name="constructorResolver">The specified <see cref="Func{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax UseCustomConstructorResolver( Func<IConstructorResolver> constructorResolver);
    }

    /// <summary>
    /// Specific fluent syntax for type binding.
    /// </summary>
    public interface ITypeUseSyntax<T> : IBindingBuilder
    {
        /// <summary>
        /// Indicates that the service should be use reflection activator for create new instance of object.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> UseReflectionActivator();

#if !NETFX_CORE
        /// <summary>
        /// Indicates that the service should be use emit activator for create new instance of object.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> UseEmitActivator();
#endif
#if !NOEXPRESSION

        /// <summary>
        /// Indicates that the service should be use expression activator for create new instance of object.
        /// </summary>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> UseExpressionActivator();
#endif

        /// <summary>
        /// Indicates that the service should be use custom activator for create new instance of object.
        /// </summary>
        /// <param name="activator">The specified <see cref="IActivator"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> UseCustomActivator(IActivator activator);

        /// <summary>
        /// Indicates that the service should be use custom activator for create new instance of object.
        /// </summary>
        /// <param name="methodActivator">The specified <see cref="Func{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> UseCustomActivator(Func<IActivator> methodActivator);

        /// <summary>
        /// Indicates that the service should be use custom constructor resolver for select constructor for specified service.
        /// </summary>
        /// <param name="constructorResolver">The specified <see cref="IConstructorResolver"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> UseCustomConstructorResolver(IConstructorResolver constructorResolver);

        /// <summary>
        /// Indicates that the service should be use custom constructor resolver for select constructor for specified service.
        /// </summary>
        /// <param name="constructorResolver">The specified <see cref="Func{T}"/>.</param>
        /// <returns>The fluent syntax.</returns>
        ITypeCallbackObjectUseWithSyntax<T> UseCustomConstructorResolver( Func<IConstructorResolver> constructorResolver);
    }
}